#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hs/hs.h>

#define BUFFER_SIZE 1024

// 定义一个回调函数，当匹配时被调用
static int on_match(unsigned int id, unsigned long long from,
        unsigned long long to, unsigned int flags, void *ctx);

int main()
{
    char *pat = "hello";

    // 编译正则表达式
    hs_database_t *database;
    hs_compile_error_t *compile_err;
    // 指定流模式
    hs_error_t err = hs_compile(pat, HS_FLAG_DOTALL, HS_MODE_STREAM,
                                NULL, &database, &compile_err);
    if (err != HS_SUCCESS) {
        fprintf(stderr, "ERROR: Unable to compile pattern \"%s\": %s\n",
                pat, compile_err->message);
        hs_free_compile_error(compile_err);
        return 1;
    }

    // 分配临时空间(指针必须初始化为NULL)
    hs_scratch_t *scratch = NULL;
    if(hs_alloc_scratch(database, &scratch) != HS_SUCCESS)
    {
        fprintf(stderr, "ERROR: Unable to allocate scratch space.
                Exiting.\n");
        hs_free_database(database);
        exit(EXIT_FAILURE);
    }

    // 创建流匹配指针
    hs_stream_t *stream;
    err = hs_open_stream(database, 0, &stream);
    if (err != HS_SUCCESS) {
        fprintf(stderr, "ERROR: Unable to open stream: %d\n", err);
        hs_free_database(database);
        return 1;
    }

    // 从标准输入流中读取数据，并匹配
    // 单模+流匹配
    unsigned char buffer[BUFFER_SIZE];
    size_t bytes_read;
    while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, stdin)) > 0 ) {
        hs_scan_stream(stream, (const char *)buffer, bytes_read, 0,
                       scratch, on_match, pat);
    }

    // 关闭流
    hs_close_stream(stream, scratch, NULL, NULL);
    // 释放空间
    hs_free_database(database);
    hs_free_scratch(scratch);

    return 0;
}

// 定义一个回调函数，当匹配时被调用
static int on_match(unsigned int id, unsigned long long from,
        unsigned long long to, unsigned int flags, void *ctx)
{
    char *tmp = (char*)ctx;

    printf("The pattern is %s\n", tmp);
    printf("Match found at end offset %llu\n", to);

    return 0;
}
